package com.sprouting.ops.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.sprouting.ops.annotations.invoke.IdempotentSingle;
import com.sprouting.ops.interfaces.AddGroup;
import com.sprouting.ops.interfaces.ConstantBase;
import com.sprouting.ops.interfaces.UpdGroup;
import com.sprouting.ops.model.OpsDep;
import com.sprouting.ops.model.OpsUser;
import com.sprouting.ops.model.ResultJson;
import com.sprouting.ops.model.bo.DepBo;
import com.sprouting.ops.model.vo.DepTree;
import com.sprouting.ops.model.vo.UserSimpleVo;
import com.sprouting.ops.service.OpsDepService;
import com.sprouting.ops.service.OpsUserService;
import com.sprouting.ops.utils.CheckTool;
import com.sprouting.ops.utils.EntityTool;
import com.sprouting.ops.utils.IdTool;
import com.sprouting.ops.utils.UserTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (Dept)表控制层
 *
 * @author longx
 * @since 2023-03-19 22:44:34
 */
@Slf4j
@RestController
@RequestMapping("dep")
public class OpsDepController {

    @Autowired
    private OpsDepService opsDepService;
    @Autowired
    private OpsUserService opsUserService;


    /**
     * 获取可选的部门负责人
     * 部门负责人只能从部门中产生-不含下级部门
     * @param deptId 部门ID
     * @return
     */
    @PostMapping("getDeptUser")
    public ResultJson getDeptUser(String deptId){
        if (CheckTool.checkNull(deptId)){
            return ResultJson.errorCheck();
        }

        List<OpsUser> deptUserList = opsUserService.getDeptUser(deptId);
        if (CollUtil.isEmpty(deptUserList)){
            return ResultJson.success();
        }

        List<UserSimpleVo> userSimpleList = BeanUtil.copyToList(deptUserList, UserSimpleVo.class);
        return ResultJson.success(userSimpleList);
    }

    /**
     * 保存部门
     * @param bo 部门信息
     * @return
     */
    @IdempotentSingle
    @PostMapping("saveDept")
    public ResultJson<OpsDep> saveDept(@Validated(AddGroup.class) DepBo bo){
        String msg = checkDept(bo);
        if (msg != null){
            return ResultJson.error(msg);
        }

        if (ConstantBase.DefaultValue.STRING.equals(bo.getParentId())){
            return ResultJson.error("不允许创建根部门");
        }

        OpsDep dept = BeanUtil.copyProperties(bo, OpsDep.class);
        dept.setId(IdTool.getId());
        EntityTool.saveBase(dept);
        // 添加上级部门
        String parentMsg = addParent(dept);
        if (parentMsg != null){
            return ResultJson.error(parentMsg);
        }

        opsDepService.save(dept);
        return ResultJson.success(dept);
    }

    /**
     * 更新部门
     * @param bo 部门信息
     * @return
     */
    @IdempotentSingle
    @PostMapping("updDept")
    public ResultJson updDept(@Validated(UpdGroup.class) DepBo bo){
        String msg = checkDept(bo);
        if (msg != null){
            return ResultJson.error(msg);
        }
        OpsDep dept = BeanUtil.copyProperties(bo, OpsDep.class);
        EntityTool.updBase(dept);
        dept.setParentIds(null);
        dept.setParentId(null);
        opsDepService.updateById(dept);
        return ResultJson.success(dept);
    }


    /**
     * 根据部门id删除部门
     * @param id 部门ID
     * @return
     */
    @PostMapping("delDeptById")
    public ResultJson delDeptById(String id){
        if (CheckTool.checkNull(id)){
            return ResultJson.errorCheck();
        }
        OpsDep dep = opsDepService.getById(id);
        if (dep == null){
            return ResultJson.success();
        }
        if (ConstantBase.DefaultValue.STRING.equals(dep.getParentId())){
            return ResultJson.error("基础部门不允许删除");
        }
        List<OpsDep> sonList = opsDepService.getByParentId(id);
        if (CollUtil.isNotEmpty(sonList)){
            return ResultJson.error("请先删除部门下的子部门");
        }
        OpsUser user = opsUserService.getByDeptIdTop1(id);
        if (user != null){
            return ResultJson.error("部门已绑定用户，请先解除绑定");
        }

        opsDepService.removeById(dep);
        return ResultJson.success();
    }

    /**
     * 获取部门树，只显示当前用户下的部门树
     * @return
     */
    @RequestMapping("getDepTree")
    public ResultJson getDepTree(){
        OpsUser loginUser = UserTool.getLoginUser();
        if (CheckTool.checkNull(loginUser.getDepId())){
            return ResultJson.error("用户未绑定部门");
        }
        // 获取全部的部门信息
        List<DepTree> depTreeList = opsDepService.getAllDept();
        // 获取到当前的部门
        DepTree deptRoot = depTreeList.stream().filter(obj -> loginUser.getDepId().equals(obj.getId())).findFirst().orElse(null);
        if (deptRoot == null){
            return ResultJson.error("用户隶属部门不存在");
        }

        getTree(depTreeList, deptRoot);
        return ResultJson.success(ListUtil.of(deptRoot));
    }

    /**
     * 添加上级部门
     * @param dept 部门信息
     * @return 非null则添加的时候出错了
     */
    private String addParent(OpsDep dept){
        if (ConstantBase.DefaultValue.STRING.equals(dept.getParentId())){
            // 最上级
        } else {
            // 存在上级
            OpsDep parent = opsDepService.getById(dept.getParentId());
            if (parent == null){
                log.error("上级部门错误，不存在的上级。{}", dept.getParentId());
                return "非法上级部门";
            }

            if (StrUtil.isEmpty(parent.getParentIds())){
                // 上级节点是顶级节点，没有上级，直接填上级即可
                dept.setParentIds(parent.getId());
            } else {
                dept.setParentIds(parent.getParentIds() + "," + parent.getId());
            }
        }

        return null;
    }

    /**
     * 获取部门树
     * @param allList 查询的全部部门树节点
     * @param parentNode 上级部门
     * @return
     */
    private void getTree(List<DepTree> allList, DepTree parentNode){
        List<DepTree> childList = allList.stream().filter(obj -> parentNode.getId().equals(obj.getParentId())).sorted(Comparator.comparing(DepTree::getCreateTime)).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(childList)){
            parentNode.setChildren(childList);
            // 子节点继续循环
            for (DepTree dept : childList){
                dept.setParentName(parentNode.getName());
                getTree(allList, dept);
            }
        }
    }

    /**
     * 检查部门信息
     * @param bo 部门
     * @return 非null则有错误
     */
    private String checkDept(DepBo bo) {
        OpsDep dbDep = opsDepService.getByNameFilterId(bo.getId(), bo.getName());
        if (dbDep != null){
            return String.format("部门名称[%s]已注册，请勿重复注册", bo.getName());
        }
        OpsDep codeDep = opsDepService.getByCodeFilterId(bo.getId(), bo.getCode());
        if (codeDep != null){
            return String.format("部门代码[%s]已注册，请勿重复注册", bo.getCode());
        }

        return null;
    }


}

